/**
 * Copyright © 2008, EMC Corporation.
 * Redistribution and use in source and binary forms, with or without modification, 
 * are permitted provided that the following conditions are met:
 *
 *     + Redistributions of source code must retain the above copyright notice, 
 *       this list of conditions and the following disclaimer.
 *     + Redistributions in binary form must reproduce the above copyright 
 *       notice, this list of conditions and the following disclaimer in the 
 *       documentation and/or other materials provided with the distribution.
 *     + The name of EMC Corporation may not be used to endorse or promote 
 *       products derived from this software without specific prior written 
 *       permission.
 *
 *      THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
 *      "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 
 *      TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
 *      PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 
 *      BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
 *      CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
 *      SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
 *      INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 *      CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
 *      ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
 *      POSSIBILITY OF SUCH DAMAGE.
 */
package com.emc.esu.api {
	import flash.utils.ByteArray;
	
	import mx.controls.List;
	
	/**
	 * This interface defines the basic operations available through the ESU web
	 * services.
	 */
	public interface EsuApi {
	    /**
	     * Creates a new object in the cloud.  The ID of the new object
	     * will be returned through the callback.
	     * @param acl Access control list for the new object.  May be null
	     * to use a default ACL
	     * @param metadata Metadata for the new object.  May be null for
	     * no metadata.
	     * @param data The initial contents of the object.  May be appended
	     * to later.  May be null to create an object with no content.
	     * @param mimeType the MIME type of the content.  Optional, 
	     * may be null.  If data is non-null and mimeType is null, the MIME
	     * type will default to application/octet-stream.
	     * @param callback a callback function with the signature 
	     * <code>function x( state:EsuCallbackState );</code>
	     * @param state an optional user-defined state object to be passed to
	     * the callback method through the EsuCallbackState object.
	     * @param checksum if not null, use the Checksum object to compute
	     * the checksum for the create object request.  If appending
	     * to the object with subsequent requests, use the same
	     * checksum object for each request.
	     */
	    function createObject( acl:Acl, metadata:MetadataList, 
	            data:ByteArray, mimeType:String, callback:Function, state:Object, checksum:Checksum = null ):void;
	    	 
	    /**
	     * Creates a new object in the cloud on the given path.  The
	     * ID of the new object will be returned through the callback.
	     * @param path ObjectPath the path to create the new object on.
	     * @param acl Access control list for the new object.  May be null
	     * to use a default ACL
	     * @param metadata Metadata for the new object.  May be null for
	     * no metadata.
	     * @param data The initial contents of the object.  May be appended
	     * to later.  May be null to create an object with no content.
	     * @param mimeType the MIME type of the content.  Optional, 
	     * may be null.  If data is non-null and mimeType is null, the MIME
	     * type will default to application/octet-stream.
	     * @param callback a callback function with the signature 
	     * <code>function x( state:EsuCallbackState );</code>
	     * @param state an optional user-defined state object to be passed to
	     * the callback method through the EsuCallbackState object.
	     * @param checksum if not null, use the Checksum object to compute
	     * the checksum for the create object request.  If appending
	     * to the object with subsequent requests, use the same
	     * checksum object for each request.
	     */
	    function createObjectOnPath( path:ObjectPath, acl:Acl, metadata:MetadataList, 
	            data:ByteArray, mimeType:String, callback:Function, state:Object, checksum:Checksum = null ):void;
	   	   
	            
	    /**
	     * Updates an object in the cloud.
	     * @param id The ID of the object to update
	     * @param acl Access control list for the new object. Optional, default
	     * is NULL to leave the ACL unchanged.
	     * @param metadata Metadata list for the new object.  Optional,
	     * default is NULL for no changes to the metadata.
	     * @param data The new contents of the object.  May be appended
	     * to later. Optional, default is NULL (no content changes).
	     * @param extent portion of the object to update.  May be null to indicate
	     * the whole object is to be replaced.  If not null, the extent size must
	     * match the data size.
	     * @param mimeType the MIME type of the content.  Optional, 
	     * may be null.  If data is non-null and mimeType is null, the MIME
	     * type will default to application/octet-stream.
	     * @param callback a callback function with the signature 
	     * <code>function x( state:EsuCallbackState );</code>
	     * @param state an optional user-defined state object to be passed to
	     * the callback method through the EsuCallbackState object.
	     * @param checksum if not null, use the Checksum object to compute
	     * the checksum for the update object request.  If appending
	     * to the object with subsequent requests, use the same
	     * checksum object for each request.
	     */
	    function updateObject( id:Identifier, acl:Acl, metadata:MetadataList, 
	            extent:Extent, data:ByteArray, mimeType:String, callback:Function, state:Object, checksum:Checksum = null ):void;
	    
	    /**
	     * Writes the metadata into the object. If the tag does not exist, it is 
	     * created and set to the corresponding value. If the tag exists, the 
	     * existing value is replaced.
	     * @param id the identifier of the object to update
	     * @param metadata metadata to write to the object.
	     * @param callback a callback function with the signature 
	     * <code>function x( state:EsuCallbackState );</code>
	     * @param state an optional user-defined state object to be passed to
	     * the callback method through the EsuCallbackState object.
	     */
	    function setUserMetadata( id:Identifier, metadata:MetadataList, callback:Function, state:Object ):void;
	    
	    /**
	     * Sets (overwrites) the ACL on the object.
	     * @param id the identifier of the object to change the ACL on.
	     * @param acl the new ACL for the object.
	     * @param callback a callback function with the signature 
	     * <code>function x( state:EsuCallbackState );</code>
	     * @param state an optional user-defined state object to be passed to
	     * the callback method through the EsuCallbackState object.
	     */
	    function setAcl( id:Identifier, acl:Acl, callback:Function, state:Object ):void;
	            
	    /**
	     * Deletes an object from the cloud.
	     * @param id the identifier of the object to delete.
	     * @param callback a callback function with the signature 
	     * <code>function x( state:EsuCallbackState );</code>
	     * @param state an optional user-defined state object to be passed to
	     * the callback method through the EsuCallbackState object.
	     */
	    function deleteObject( id:Identifier, callback:Function, state:Object ):void;
	    
	    /**
	     * Fetches the user metadata for the object.
	     * @param id the identifier of the object whose user metadata
	     * to fetch.
	     * @param tags A list of user metadata tags to fetch.  Optional.  If null,
	     * all user metadata will be fetched.
	     * @param callback a callback function with the signature 
	     * <code>function x( state:EsuCallbackState );</code>
	     * @param state an optional user-defined state object to be passed to
	     * the callback method through the EsuCallbackState object.
	     */
	    function getUserMetadata( id:Identifier, tags:MetadataTags, callback:Function, state:Object ):void;
	    
	    /**
	     * Fetches the system metadata for the object.
	     * @param id the identifier of the object whose system metadata
	     * to fetch.
	     * @param tags A list of system metadata tags to fetch.  Optional.
	     * Default value is null to fetch all system metadata.
	     * @param callback a callback function with the signature 
	     * <code>function x( state:EsuCallbackState );</code>
	     * @param state an optional user-defined state object to be passed to
	     * the callback method through the EsuCallbackState object.
	     */
	    function getSystemMetadata( id:Identifier, tags:MetadataTags, callback:Function, state:Object ):void;
	    
	    /**
	     * Reads an object's content.
	     * @param id the identifier of the object whose content to read.
	     * @param extent the portion of the object data to read.  Optional.
	     * Default is null to read the entire object.
	     * @param buffer the buffer to use to read the extent.  Must be large
	     * enough to read the response or an error will be thrown.  If null,
	     * a buffer will be allocated to hold the response data.  If you pass
	     * a buffer that is larger than the extent, only extent.getSize() bytes
	     * will be valid.
	     * @param callback a callback function with the signature 
	     * <code>function x( state:EsuCallbackState );</code>
	     * @param state an optional user-defined state object to be passed to
	     * the callback method through the EsuCallbackState object.
	     * @param checksum if not null, the given checksum object will be used
	     * to verify checksums during the read operation.  Note that only erasure
	     * coded objects will return checksums *and* if you're reading the object
	     * in chunks, you'll have to read the data back sequentially to keep
	     * the checksum consistent.  If the read operation does not return
	     * a checksum from the server, the checksum operation will be skipped.
	     */
	    function readObject( id:Identifier, extent:Extent, buffer:ByteArray, callback:Function, state:Object, checksum:Checksum = null ):void;
	    
	    /**
	     * Returns an object's ACL
	     * @param id the identifier of the object whose ACL to read
	     * @param callback a callback function with the signature 
	     * <code>function x( state:EsuCallbackState );</code>
	     * @param state an optional user-defined state object to be passed to
	     * the callback method through the EsuCallbackState object.
	     */
	    function getAcl( id:Identifier, callback:Function, state:Object ):void;
	    
	    /**
	     * Deletes metadata items from an object.
	     * @param id the identifier of the object whose metadata to 
	     * delete.
	     * @param tags the list of metadata tags to delete.
	     * @param callback a callback function with the signature 
	     * <code>function x( state:EsuCallbackState );</code>
	     * @param state an optional user-defined state object to be passed to
	     * the callback method through the EsuCallbackState object.
	     */
	    function deleteUserMetadata( id:Identifier, tags:MetadataTags, callback:Function, state:Object ):void;
	    
	    /**
	     * Lists the versions of an object.
	     * @param id the object whose versions to list.
	     * @param callback a callback function with the signature 
	     * <code>function x( state:EsuCallbackState );</code>
	     * @param state an optional user-defined state object to be passed to
	     * the callback method through the EsuCallbackState object.
	     */
	    function listVersions( id:Identifier, callback:Function, state:Object ):void;
	    
	    /**
	     * Creates a new immutable version of an object.
	     * @param id the object to version
	     * @param callback a callback function with the signature 
	     * <code>function x( state:EsuCallbackState );</code>
	     * @param state an optional user-defined state object to be passed to
	     * the callback method through the EsuCallbackState object.
	     */
	    function versionObject( id:Identifier, callback:Function, state:Object ):void;
	    
	    /**
	     * Deletes a version
	     * @param id the version object to delete
	     * @param callback a callback function with the signature 
	     * <code>function x( state:EsuCallbackState );</code>
	     * @param state an optional user-defined state object to be passed to
	     * the callback method through the EsuCallbackState object.
	     */
	    function deleteVersion( id:ObjectId, callback:Function, state:Object ):void;
	    
	    /**
	     * Restores a version of an object to the base revision (i.e. "promotes" a
	     * version to the current version)
	     * @param id the base object
	     * @param vId the version ID to promote
	     * @param callback a callback function with the signature 
	     * <code>function x( state:EsuCallbackState );</code>
	     * @param state an optional user-defined state object to be passed to
	     * the callback method through the EsuCallbackState object.
	     */
	    function restoreVersion( id:Identifier, vId:ObjectId, callback:Function, state:Object ):void;
	    
	    /**
	     * Lists all objects with the given tag.
	     * @param tag the tag to search for.  May be a MetadataTag object
	     * or a String containing the tag name.
		 * @param options options for returning the list
	     * @return The list of objects with the given tag.  If no objects
	     * are found the array will be empty.
	     * @param callback a callback function with the signature 
	     * <code>function x( state:EsuCallbackState );</code>
	     * @param state an optional user-defined state object to be passed to
	     * the callback method through the EsuCallbackState object.
	     */
	    function listObjects( tag:Object, options:ListOptions, callback:Function, state:Object ):void;
	    
		/**
	     * Lists all objects with the given tag.  Returns the IDs and metadata
	     * of all objects matching the tag.
	     * @param tag the tag to search for.  May be a MetadataTag object
	     * or a String containing the tag name.
	     * @return An array of Objects.  Each object will have a property
	     * named 'id' containing the ObjectId and a property named 'meta'
	     * containing the ObjectMetadata.
	     * @param callback a callback function with the signature 
	     * <code>function x( state:EsuCallbackState );</code>
	     * @param state an optional user-defined state object to be passed to
	     * the callback method through the EsuCallbackState object.
	     */
		[Deprecated("Use the ListOptions object in the listObjects function for better control over the results")]
	    function listObjectsWithMetadata( tag:Object, callback:Function, state:Object ):void;
	    
	    /**
	     * Returns a list of the tags that are listable the current user's tennant.
	     * @param tag optional.  If specified, the list will be limited to the tags
	     * under the specified tag.  If null, only top level tags will be returned.
	     * May be a MetadataTag object or a String containing the tag name.
	     * @param callback a callback function with the signature 
	     * <code>function x( state:EsuCallbackState );</code>
	     * @param state an optional user-defined state object to be passed to
	     * the callback method through the EsuCallbackState object.
	     */
	    function getListableTags( tag:Object, callback:Function, state:Object ):void;
	    
	    /**
	     * Returns the list of user metadata tags assigned to the object.
	     * @param id the object whose metadata tags to list
	     * @param callback a callback function with the signature 
	     * <code>function x( state:EsuCallbackState );</code>
	     * @param state an optional user-defined state object to be passed to
	     * the callback method through the EsuCallbackState object.
	     */
	    function listUserMetadataTags( id:Identifier, callback:Function, state:Object ):void;
	    
	    /**
	     * Executes a query for objects matching the specified XQuery string.
	     * @param xquery the XQuery string to execute against the cloud.
	     * @return the list of objects matching the query.  If no objects
	     * are found, the array will be empty.
	     * @param callback a callback function with the signature 
	     * <code>function x( state:EsuCallbackState );</code>
	     * @param state an optional user-defined state object to be passed to
	     * the callback method through the EsuCallbackState object.
	     */
	    function queryObjects( xquery:String, callback:Function, state:Object ):void;

	    /**
	     * Returns all the metadata for the object: system metadata, user
	     * metadata, and the ACL as a ObjectMetadata object.
	     * @param id the object whose metadata to get
	     * @param callback a callback function with the signature 
	     * <code>function x( state:EsuCallbackState );</code>
	     * @param state an optional user-defined state object to be passed to
	     * the callback method through the EsuCallbackState object.
	     */
		function getAllMetadata( id:Identifier, callback:Function, state:Object ):void;
		
		/**
		 * Returns all the objects in the specified directory as an array
		 * of DirectoryEntry objects.
		 * @param id the object whose metadata to get
		 * @param options options for listing the directory
		 * @param callback a callback function with the signature 
		 * <code>function x( state:EsuCallbackState );</code>
		 * @param state an optional user-defined state object to be passed to
		 * the callback method through the EsuCallbackState object.
		 */
		function listDirectory( path:ObjectPath, options:ListOptions, callback:Function, state:Object ):void;
		
		/**
		 * Returns the replica information for the object.
	     * @param id the object whose metadata to get
	     * @param callback a callback function with the signature 
	     * <code>function x( state:EsuCallbackState );</code>
	     * @param state an optional user-defined state object to be passed to
	     * the callback method through the EsuCallbackState object.
		 */
		function getObjectInfo( id:Identifier, callback:Function, state:Object ):void;
		
		/**
	     * An Atmos user (UID) can construct a pre-authenticated URL to an 
	     * object, which may then be used by anyone to retrieve the 
	     * object (e.g., through a browser). This allows an Atmos user 
	     * to let a non-Atmos user download a specific object. The 
	     * entire object/file is read.
	     * 
	     * This method is synchronous, therefore no callback is needed.
	     * 
	     * @param id the object to generate the URL for
	     * @param expiration the expiration date of the URL
	     * @return a URL that can be used to share the object's content
	     */
	    function getShareableUrl( id:Identifier, expiration:Date ):String;
	    
	    /**
	     * Renames a file or directory within the namespace.
	     * @param source The file or directory to rename
	     * @param destination The new path for the file or directory
	     * @param force If true, the desination file or 
	     * directory will be overwritten.  Directories must be empty to be 
	     * overwritten.  Also note that overwrite operations on files are
	     * not synchronous; a delay may be required before the object is
	     * available at its destination.
	     * @param callback a callback function with the signature 
	     * <code>function x( state:EsuCallbackState );</code>
	     * @param state an optional user-defined state object to be passed to
	     * the callback method through the EsuCallbackState object.
	     */
	    function rename(source:ObjectPath, destination:ObjectPath, force:Boolean, callback:Function, state:Object):void;

	    /**
	     * Gets the current Atmos server information.  Currently, this simply
	     * returns the version of Atmos that is running.
	     * @param callback a callback function with the signature 
	     * <code>function x( state:EsuCallbackState );</code>
	     * @param state an optional user-defined state object to be passed to
	     * the callback method through the EsuCallbackState object.
	     */
	    function getServiceInformation(callback:Function, state:Object):void;
	}
}